package ltd.newbee.mall.config;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: qzx
 * @date: 2022-08-13 22:10
 * @version: 1.0
 */
@Component
@Slf4j
@AllArgsConstructor
public class RedissonTemplate {

    private final RedissonClient redissonClient;

    private RLock getLock(String lockKey) {
        String DEFAULT_LOCK_NAME = "lock-";
        String key = DEFAULT_LOCK_NAME + lockKey;
        return redissonClient.getLock(key);
    }

    public boolean lock(String lockKey, long timeout) {
        try {
            RLock lock = getLock(lockKey);
            if (timeout != -1) {
                lock.lock(timeout, TimeUnit.SECONDS);
            } else {
                lock.lock();
            }
            log.debug(" get lock success ,lockKey:{}", lockKey);
            return true;
        } catch (Exception e) {
            log.error(" get lock fail,lockKey:{}, cause:{} ", lockKey, e.getMessage());
            return false;
        }
    }

    /**
     * 解锁
     *
     * @param lockKey
     */
    public void unlock(String lockKey) {
        try {
            RLock lock = getLock(lockKey);
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
                log.info("key：{}，unlock success", lockKey);
            } else {
                log.warn("key：{}，没有加锁或者不是当前线程加的锁 ", lockKey);
            }
        } catch (Exception e) {
            log.error("key：{}，unlock error,reason:{}", lockKey, e.getMessage());
        }
    }

    public boolean tryLock(String lockKey, int waitTime, int leaseTime, TimeUnit unit) {
        RLock lock = getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (InterruptedException e) {
            log.error("key：{}，unlock error,reason:{}", lockKey, e.getMessage());
            return false;
        }
    }

}
